define(["require", "exports"], function (require, exports) {
	'use strict';

	var has = Object.prototype.hasOwnProperty;

	/**
	 * Decode a URI encoded string.
	 *
	 * @param {String} input The URI encoded string.
	 * @returns {String} The decoded string.
	 * @api private
	 */
	function decode(input) {
		return decodeURIComponent(input.replace(/\+/g, ' '));
	}

	/**
	 * Simple query string parser.
	 *
	 * @param {String} query The query string that needs to be parsed.
	 * @returns {Object}
	 * @api public
	 */
	function querystring(query) {
		var parser = /([^=?&]+)=?([^&]*)/g
			, result = {}
			, part;

		while (part = parser.exec(query)) {
			var key = decode(part[1])
				, value = decode(part[2]);

			//
			// Prevent overriding of existing properties. This ensures that build-in
			// methods like `toString` or __proto__ are not overriden by malicious
			// querystrings.
			//
			if (key in result) continue;
			result[key] = value;
		}

		return result;
	}

	/**
	 * Transform a query string to an object.
	 *
	 * @param {Object} obj Object that should be transformed.
	 * @param {String} prefix Optional prefix.
	 * @returns {String}
	 * @api public
	 */
	function querystringify(obj, prefix) {
		prefix = prefix || '';

		var pairs = [];

		//
		// Optionally prefix with a '?' if needed
		//
		if ('string' !== typeof prefix) prefix = '?';

		for (var key in obj) {
			if (has.call(obj, key)) {
				pairs.push(encodeURIComponent(key) + '=' + encodeURIComponent(obj[key]));
			}
		}

		return pairs.length ? prefix + pairs.join('&') : '';
	}

	//
	// Expose the module.
	//
	exports.stringify = querystringify;
	exports.parse = querystring;
});